//
//  GNTableView.m
//  SuperApp
//
//  Created by wGN on 2021/5/28.
//  Copyright © 2021 chaos network technology. All rights reserved.
//

#import "GNTableView.h"

@implementation GNTableView

- (instancetype)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
        [self config];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style{
    if (self = [super initWithFrame:frame style:style]) {
        [self config];
    }
    return self;
}

- (void)setGNdelegate:(id<GNTableViewProtocol>)GNdelegate{
    _GNdelegate = GNdelegate;
    self.dataSource = self;
    self.delegate = self;
}

- (instancetype)initWithCoder:(NSCoder *)coder{
    self = [super initWithCoder:coder];
    if (self) {
        [self config];
    }
    return self;
}

- (void)config{
    self.pageNum = 1;
    self.backgroundColor = wColor_bg;
    self.separatorStyle = UITableViewCellSeparatorStyleNone;
    self.estimatedRowHeight = 44;
    self.rowHeight = UITableViewAutomaticDimension;
    self.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
    if (@available(iOS 11.0, *)) {
        self.estimatedSectionHeaderHeight = 0;
        self.estimatedSectionFooterHeight = 0;
        self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    }
    if (@available(iOS 13.0, *)) {
        self.automaticallyAdjustsScrollIndicatorInsets = false;
    }
    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000
    if (@available(iOS 15.0, *)) {
        self.sectionHeaderTopPadding = 0;
    }
    #endif
    self.reuse = YES;
    self.showsHorizontalScrollIndicator = NO;
    self.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, CGFLOAT_MIN)];
    self.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, CGFLOAT_MIN)];
}

- (NSInteger)numberOfSectionsInTableView:(GNTableView *)tableView{
    if ([self.GNdelegate respondsToSelector:@selector(numberOfSectionsInGNTableView:)]) {
        self.dataArr = [self.GNdelegate numberOfSectionsInGNTableView:self];
        return self.dataArr.count;
    }else if ([self.GNdelegate respondsToSelector:@selector(numberOfRowsInGNTableView:)]) {
        GNSectionModel *sectionModel = [GNSectionModel new];
        sectionModel.rows = (NSMutableArray*)[self.GNdelegate numberOfRowsInGNTableView:self];
        self.dataArr = @[sectionModel];
        return 1;
    }
    return 0;
}

-(UITableViewCell *)tableView:(GNTableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    id<GNRowModelProtocol> model = [self.dataArr[indexPath.section].rows objectAtIndex:indexPath.row];
    BaseTableViewCell  *cell = nil;
    if ([model conformsToProtocol:@protocol(GNRowModelProtocol)]) {
        model.indexPath = indexPath;
        Class cellClass = nil;
        if ([self.GNdelegate respondsToSelector:@selector(classOfGNTableView:atIndexPath:)]) {
            Class class = [self.GNdelegate classOfGNTableView:tableView atIndexPath:indexPath];
            cellClass = class;
        }else{
            cellClass = model.cellClass;
        }
        if (!cellClass) return BaseTableViewCell.new;
        NSString *identifier = NSStringFromClass(cellClass);
        if (self.reuse) {
            cell = [tableView dequeueReusableCellWithIdentifier:identifier];
        }else{
            cell = [tableView cellForRowAtIndexPath:indexPath];
        }
        if (model.xib) {
            if (!cell)
                cell = [[[NSBundle mainBundle]  loadNibNamed:NSStringFromClass(cellClass) owner:nil options:nil] lastObject];
        }else{
            if (!cell)
                cell = [[cellClass alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
        }
        cell.contentView.backgroundColor = model.backgroundColor?:UIColor.whiteColor;
        cell.selectionStyle = model.selectionStyle;
        cell.accessoryType = model.accessoryType;
        if ([cell respondsToSelector:@selector(setGNModel:)]) [cell setGNModel:model];
    }
    return cell?:[UITableViewCell new];
}

- (NSInteger)tableView:(nonnull GNTableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return (self.dataArr.count > section)?self.dataArr[section].rows.count:0 ;
}

- (CGFloat)tableView:(GNTableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    CGFloat height = 0;
    if ([self.dataArr[indexPath.section].rows objectAtIndex:indexPath.row].hidden) {
        height = 0;
    }else{
        height = [self.dataArr[indexPath.section].rows objectAtIndex:indexPath.row].cellHeight?:(self.dataArr[indexPath.section].cellHeight?:UITableViewAutomaticDimension);
    }
    return height;
}

- (CGFloat)tableView:(GNTableView *)tableView heightForHeaderInSection:(NSInteger)section {
    GNSectionModel *sectionModel = self.dataArr[section];
    if ((sectionModel.headerModel.title && sectionModel.headerModel.title.length)||
        ![sectionModel.headerClass isEqual:GNTableHeaderFootView.class])
        return sectionModel.headerHeight > 0.01? sectionModel.headerHeight :UITableViewAutomaticDimension;
    
    if (sectionModel.headerHeight == 0.01 && self.style == UITableViewStylePlain)
        return 0;
    
    return  sectionModel.headerHeight;
}

- (CGFloat)tableView:(GNTableView *)tableView heightForFooterInSection:(NSInteger)section {
    GNSectionModel *sectionModel = self.dataArr[section];
    if ((sectionModel.footerModel.title && sectionModel.footerModel.title.length)||
        ![sectionModel.footerClass isEqual:GNTableHeaderFootView.class])
        return sectionModel.footerHeight > 0.01?sectionModel.footerHeight:UITableViewAutomaticDimension;
    
    if (sectionModel.footerHeight == 0.01 && self.style == UITableViewStylePlain)
        return 0;
    
    return sectionModel.footerHeight;
}

- (UIView *)tableView:(GNTableView *)tableView viewForHeaderInSection:(NSInteger)section {
    GNSectionModel *sectionModel = self.dataArr[section];
    GNTableHeaderFootView *headView = nil;
    if (sectionModel.headerXib) {
        headView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:NSStringFromClass(sectionModel.headerClass)];
        if (!headView) {
            headView = [[[NSBundle mainBundle]  loadNibNamed:NSStringFromClass(sectionModel.headerClass) owner:nil options:nil] lastObject];
        }
    }else{
        headView = [sectionModel.headerClass headerWithTableView:tableView];
    }
    [headView setGNModel:sectionModel.headerModel];
    return headView;
}

- (UIView *)tableView:(GNTableView *)tableView viewForFooterInSection:(NSInteger)section {
    GNSectionModel *sectionModel = self.dataArr[section];
    GNTableHeaderFootView *footerView = nil;
    if (sectionModel.footerXib) {
        footerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:NSStringFromClass(sectionModel.footerClass)];
        if (!footerView) {
            footerView = [[[NSBundle mainBundle]  loadNibNamed:NSStringFromClass(sectionModel.footerClass) owner:nil options:nil] lastObject];
        }
    }else{
        footerView = [sectionModel.footerClass headerWithTableView:tableView];
    }
    [footerView setGNModel:sectionModel.footerModel];
    return footerView;
}

- (void)tableView:(GNTableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    if (self.GNdelegate && [self.GNdelegate respondsToSelector:@selector(GNTableView:didSelectRowAtIndexPath:data:)]) {
        [self.GNdelegate GNTableView:self didSelectRowAtIndexPath:indexPath data:[self.dataArr[indexPath.section].rows objectAtIndex:indexPath.row]];
    }
}

- (void)tableView:(GNTableView *)tableView willDisplayCell:(BaseTableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
    id<GNRowModelProtocol> model = [self.dataArr[indexPath.section].rows objectAtIndex:indexPath.row];
    [cell hd_endSkeletonAnimation];
    if (!model.isNotCacheheight) {
        model.cellHeight = cell.frame.size.height;
    }
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    if (self.GNdelegate && [self.GNdelegate respondsToSelector:@selector(gnScrollViewDidScroll:)]) {
        [self.GNdelegate gnScrollViewDidScroll:scrollView];
    }
    if (self.topSop && scrollView.contentOffset.y < 0) {
        scrollView.contentOffset = CGPointMake(scrollView.contentOffset.x, 0);
    }
}

- (void)setNeedRefreshHeader:(BOOL)needRefreshHeader{
    _needRefreshHeader = needRefreshHeader;
    if (needRefreshHeader) {
        @HDWeakify(self)
        self.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
            @HDStrongify(self)
            self.pageNum = 1;
            if (self.requestNewDataHandler) self.requestNewDataHandler();
        }];
    }else{
        self.mj_header = nil;
    }
}

- (void)setNeedRefreshFooter:(BOOL)needRefreshFooter{
    _needRefreshFooter = needRefreshFooter;
    if (needRefreshFooter) {
        @HDWeakify(self)
        self.mj_footer = [MJRefreshAutoNormalFooter  footerWithRefreshingBlock:^{
            @HDStrongify(self)
            if (!self.pageNum) self.pageNum = 1;
            self.pageNum += 1;
            if (self.requestMoreDataHandler) self.requestMoreDataHandler();
        }];
    }else{
        self.mj_footer = nil;
    }
}

- (void)reloadData:(BOOL)isNoMore{
    [self reloadData];
    if (self.needShowErrorView || self.needShowNoDataView) [self hd_removePlaceholderView];
    [self hd_removePlaceholderView];
    if (self.pageNum == 1) {
        
        if (self.needRefreshFooter) {
            [self.mj_footer resetNoMoreData];
            if (isNoMore) {
                [self.mj_footer endRefreshingWithNoMoreData];
            } else {
                [self.mj_footer endRefreshing];
            }
        }
        if (self.needRefreshHeader && self.mj_header.isRefreshing) [self.mj_header endRefreshing];
    }else{
        if (self.needRefreshFooter) {
            if (isNoMore && self.mj_footer.isRefreshing) {
                [self.mj_footer endRefreshingWithNoMoreData];
            } else {
                [self.mj_footer endRefreshing];
            }
        }
    }
    [self showOrHideNoDataPlacholderView];
}

- (void)reloadFail{
    if (self.needShowErrorView || self.needShowNoDataView) [self hd_removePlaceholderView];
    if (self.needRefreshHeader && self.mj_header.isRefreshing) [self.mj_header endRefreshing];
    if (self.needRefreshFooter && self.mj_footer.isRefreshing) [self.mj_footer endRefreshing];
    if (self.pageNum == 1) {
        [self reloadData];
    }
    [self showOrHideNetworkErrorPlacholderView];
}

- (void)showOrHideNoDataPlacholderView {
    if (self.needShowNoDataView && !self.hd_hasData) {
        self.mj_header.hidden = YES;
        self.mj_footer.hidden = YES;
        self.placeholderViewModel.image = @"no_data";
        self.placeholderViewModel.title = @"暂无数据";
        if (self.customPlaceHolder) self.customPlaceHolder(self.placeholderViewModel,NO);
        [self hd_showPlaceholderViewWithModel:self.placeholderViewModel];
    } else {
        self.mj_header.hidden = NO;
        self.mj_footer.hidden = NO;
        [self hd_removePlaceholderView];
    }
}

- (void)showOrHideNetworkErrorPlacholderView {
    if (self.needShowErrorView && !self.hd_hasData) {
        self.mj_header.hidden = YES;
        self.mj_footer.hidden = YES;
        self.placeholderViewModel.image = @"fail_b";
        self.placeholderViewModel.title = @"网络开小差啦";
        if (self.customPlaceHolder) self.customPlaceHolder(self.placeholderViewModel,YES);
        [self hd_showPlaceholderViewWithModel:self.placeholderViewModel];
    } else {
        [self hd_removePlaceholderView];
        self.mj_header.hidden = NO;
        self.mj_footer.hidden = NO;
    }
}

- (UIViewPlaceholderViewModel *)placeholderViewModel{
    if (!_placeholderViewModel) {
        UIViewPlaceholderViewModel *placeholderViewModel = UIViewPlaceholderViewModel.new;
        placeholderViewModel.title = @"暂无数据";
        placeholderViewModel.image = @"no_data";
        placeholderViewModel.needRefreshBtn = self.needRefreshBTN;
        placeholderViewModel.refreshBtnTitle = @"刷新";
        @HDWeakify(self)
        placeholderViewModel.clickOnRefreshButtonHandler = ^{
            @HDStrongify(self)
            if (self.tappedRefreshBtnHandler) self.tappedRefreshBtnHandler();
        };
        _placeholderViewModel = placeholderViewModel;
        
    }
    return _placeholderViewModel;
}

- (BOOL)hd_hasData {
    NSInteger totalCount = 0;
    if ([self isKindOfClass:[UITableView class]]) {
        UITableView *tableView = (UITableView *)self;
        for (NSInteger section = 0; section < tableView.numberOfSections; section++) 
            totalCount += [tableView numberOfRowsInSection:section];
    } else if ([self isKindOfClass:[UICollectionView class]]) {
        UICollectionView *collectionView = (UICollectionView *)self;
        for (NSInteger section = 0; section < collectionView.numberOfSections; section++)
            totalCount += [collectionView numberOfItemsInSection:section];
    }
    
    return totalCount;
}

- (HDSkeletonLayerDataSourceProvider *)provider {
    if (!_provider) {
        _provider = [[HDSkeletonLayerDataSourceProvider alloc]
            initWithTableViewCellBlock:^UITableViewCell<HDSkeletonLayerLayoutProtocol> *(UITableView *tableview, NSIndexPath *indexPath) {
                return [BaseTableViewCell cellWithTableView:tableview];
            }
            heightBlock:^CGFloat(UITableView *tableView, NSIndexPath *indexPath) {
                return [BaseTableViewCell skeletonViewHeight];
            }];
        _provider.numberOfRowsInSection = 20;
    }
    return _provider;
}

@end
